﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static System.Threading.Thread;

namespace Project_7
{
    /// <summary>
    /// AsParallel() 并行linq查询，不管顺序，最后合并到单线程去处理
    /// AsParallel()查询结果之后的处理 ForAll() 并行linq查询，forall里面的方法和任务处理的线程是同一线程，并行方式运行forall中的方法
    /// AsParallel().AsSequential() 并行linq查询，带顺序，不会并行，耗时和普通方法一样
    /// AsParallel().AsOrdered() 并行linq查询，带顺序，会并行执行，并行执行后仔细按顺序合并结果，会影响效率，比普通方法速度更快
    /// </summary>
    public class Unit_7_03
    {
        public static void Go()
        {
            var sw = new Stopwatch();
            var cts = new CancellationTokenSource();
            sw.Start();
            var query = from t in GetTypes()
                        select EmulateProcessing(t);
            foreach (var t in query)
            {
                PrintInfo(t);
            }
            sw.Stop();
            Console.WriteLine($"----------------普通linq 查询，耗费时间：{sw.Elapsed}-------------------");

            sw.Restart();
            var parallelQuery = from t in GetTypes().AsParallel()
                                select EmulateProcessing(t);
            foreach (var item in parallelQuery)
            {
                PrintInfo(item);
            }
            sw.Stop();
            Console.WriteLine("---");
            Console.WriteLine($"----------------并行linq查询，耗费时间：{sw.Elapsed}----------------------");

            sw.Restart();
            parallelQuery = from t in GetTypes().AsParallel()
                            select EmulateProcessing(t);
            parallelQuery.ForAll(PrintInfo);
            sw.Stop();
            Console.WriteLine($"----------------并行linq查询，forall中并行处理，耗费时间：{sw.Elapsed}----------------------");

            sw.Restart();
            query = from t in GetTypes().AsParallel().AsSequential()
                    select EmulateProcessing(t);
            foreach (var item in query)
            {
                PrintInfo(item);
            }
            sw.Stop();
            Console.WriteLine($"----------------并行linq查询带AsSequential顺序，耗费时间：{sw.Elapsed}----------------------");

            sw.Restart();
            query = from t in GetTypes().AsParallel().AsOrdered()
                    select EmulateProcessing(t);
            foreach (var item in query)
            {
                PrintInfo(item);
            }
            sw.Stop();
            Console.WriteLine($"----------------并行linq查询带AsOrdered顺序，耗费时间：{sw.Elapsed}----------------------");
        }

        static void PrintInfo(string typeName)
        {
            Sleep(150);
            Console.WriteLine($"{typeName} 类型打印在线程id {CurrentThread.ManagedThreadId} 上。");
        }

        static string EmulateProcessing(string typeName)
        {
            Sleep(150);
            Console.WriteLine($"{typeName} 类型是在线程id {CurrentThread.ManagedThreadId} 上处理的。");
            return typeName;
        }

        static IEnumerable<string> GetTypes()
        {
            var result = from assembly in AppDomain.CurrentDomain.GetAssemblies()
                         from type in assembly.GetExportedTypes()
                         where type.Name.StartsWith("Task")
                         select type.Name;
            return result;
        }
    }
}
